package cn.le.container;

import java.util.*;

/**
 * 自己实现散列Map
 *
 * map是利用数组存储一个LinkedList集合,下标为key的哈希码,具体的值存储是mapentry的实体对象中,在把此实体对象放在linkedList集合中
 * 以此来实现map数据结构的数据存储
 *
 */
public class SimpleHashMap<K,V> extends AbstractMap<K,V>{

    static final int SIZE = 997;

    LinkedList<MapEntry<K,V>>[] buchets = new LinkedList[SIZE];

    public V put(K key,V value)
    {
        V oldValue = null;
        int index = Math.abs(key.hashCode()) % SIZE;

        if(buchets[index] == null)
        {
            buchets[index] = new LinkedList<MapEntry<K,V>>();
        }
        LinkedList<MapEntry<K,V>> bucket = buchets[index];
        MapEntry<K,V> pari = new MapEntry<>(key,value);
        boolean found = false;
        //验证是不是相同的key,如果key相同则替换原值
        ListIterator<MapEntry<K,V>> it = bucket.listIterator();
        while (it.hasNext())
        {
            MapEntry<K,V> iPair = it.next();
            if(iPair.getKey().equals(key))
            {
                oldValue = iPair.getValue();
                it.set(pari);
                found = true;
                break;
            }
        }
        //如果key不相同,但是是key的hash码相同,则保持在LinkedList<MapEntry<K,V>>中,说明是hash码冲突
        if(!found)
        {
            buchets[index].add(pari);
        }
        return oldValue;
    }

    public V get(Object key)
    {
        int index = Math.abs(key.hashCode()) % SIZE;
        if(buchets[index] == null)
        {
            return null;
        }
        for (MapEntry<K,V> iPair:buchets[index]) {
            if(iPair.getKey().equals(key))
            {
                return iPair.getValue();
            }
        }
        return null;
    }

    @Override
    public Set<Entry<K, V>> entrySet() {

        Set<Entry<K,V>> set = new HashSet<Entry<K,V>>();
        for (LinkedList<MapEntry<K,V>> buchet : buchets)
        {
            if (buchet == null)
            {
                continue;
            }
            for (MapEntry<K,V> mpair:buchet)
            {
                set.add(mpair);
            }
        }
        return set;
    }

    public static void main(String[] args) {

        SimpleHashMap<String,String> m = new SimpleHashMap<>();
        m.put("1","2");

        System.out.println(m.get("1"));
        System.out.println(m);

    }
}
